﻿using System;
using NUnit.Framework;
using NUnit.Framework.SyntaxHelpers;
using SimpleServiceBus.Bus;
using SimpleServiceBus.Bus.MessageManagement.MessageHandling;
using SimpleServiceBus.Bus.Pipeline;
using SimpleServiceBus.Tests.Stubs;
using SimpleServiceBus.Utilities.ObjectBuilder;

namespace SimpleServiceBus.Tests.Bus.MessageManagement.MessageHandling
{
    [TestFixture]
    public class MessageHandlerBindingTestFixture
    {
        private ServiceLocatorOnlyMessageContext _testContext;

        [TestFixtureSetUp]
        public void SetUp()
        {
            _testContext = new ServiceLocatorOnlyMessageContext();
            _testContext.RegisterService<IObjectBuilderService, DefaultObjectBuilderService>();
        }

        [Test]
        public void Can_Be_Created_And_Handle_Message()
        {
            var binding = new MessageHandlerBinding(typeof (TestHandler), typeof (Message_A));
            Assert.IsNotNull(binding.HandlerMethod);
            Assert.That(binding.HandlerMethod.Name, Is.EqualTo("Handle"));

            TestHandler.WasHandled = false;
            binding.Handle(new Message_A(), _testContext);

            Assert.IsTrue(TestHandler.WasHandled);
        }

        [Test]
        public void Interface_Based_Binding_Will_Match_Implementing_Message()
        {
            var binding = new MessageHandlerBinding(typeof (TestHandler_2), typeof (IMessageFamily_A));
            Assert.IsTrue(binding.Matches(new MessageEnvelope {Body = new Message_A()}));
            Assert.IsTrue(binding.Matches(new MessageEnvelope {Body = new AllFamilies()}));
        }

        [Test]
        public void Interface_Based_Binding_Wont_Match_Non_Implementing_Message()
        {
            var binding = new MessageHandlerBinding(typeof (TestHandler_2), typeof (IMessageFamily_A));
            Assert.IsFalse(binding.Matches(new MessageEnvelope {Body = new Message_B()}));
        }

        [Test]
        [ExpectedException(typeof(ArgumentException))]
        public void Creating_A_Binding_With_Mismatched_Types_Should_Fail()
        {
            new MessageHandlerBinding(typeof (TestHandler), typeof (IMessageFamily_A));
        }
    }

    public class TestHandler : IMessageHandler<Message_A>
    {
        public static bool WasHandled;

        #region IMessageHandler<Message_A> Members

        public void Handle(Message_A message, IMessageContext context)
        {
            WasHandled = true;
        }

        #endregion
    }

    public class TestHandler_2 : IMessageHandler<IMessageFamily_A>
    {
        public void Handle(IMessageFamily_A message, IMessageContext context)
        {
            throw new NotImplementedException();
        }
    }
}